<?php

namespace  app\index\controller;

use app\common\controller\IndexController;
use app\index\model\FundCard;
use app\index\model\FundCheck;
use app\index\model\FundCheckOy;
use app\index\model\FundCheckOyReturn;
use app\index\model\UserCashLog;
use app\index\model\Message as messageModel;
use think\App;
use think\Exception;
use think\facade\Cache;
use think\facade\Db;
use think\facade\View;
use app\index\model\FundSource;
use app\common\model\Pay;
use phpqrcode\QRcode;

/**
 * 首页管理
 * Class Index
 * @package app\admin\controller
 */
class Fund extends  IndexController {

    public function __construct(App $app)
    {
        parent::__construct($app);
        View::assign([
            'menu_class' => 'fund',
        ]);
    }

    /**
     * 首页
     * @author 救火队队长
     */
    public function  index() {

        View::layout(true);
        $user_list = Db::name('user')->where(['id'=>$this->user_id])->find();
        $grade    = $user_list['grade'];
        $grade_new = $user_list['grade_new'];
        $user_id   = $user_list['id'];
        if($grade == 0){
            return $this->redirect(url('/index/user/cardCheck'));
        }
        $fund_alipay = getSetting('fund_alipay');
        $fund_oy = 0;
        if($user_id >= 919){
            $fund_oy = 1;
            $fund_alipay = 0;
        }else{
            if($user_id==5){
                $fund_oy = 1;
                $fund_alipay = 1;
            }else if($user_id==770){
                $fund_oy = 1;
                $fund_alipay = 0;
            }
        }
//        $fund_oy = getSetting('fund_oy');
//        $is_user_oy_set = Db::name('user_oy_set')->where(['user_id' => $this->user_id])->count();
//        if($is_user_oy_set >0){
//        }else{
//            $fund_oy = 0;
//        }
        View::assign([
            'menu_child' => 'fund_index',
            'grade'     => $grade,
            'user_id'   => $this->user_id,
            'fund_server' => getSetting('fund_server'),
            'fund_alipay' => $fund_alipay,
            'fund_server_img' =>  getSetting('fund_server_img'),
            'fund_oy' => $fund_oy,
        ]);
        return View::fetch();
    }

    public function  info() {
        View::layout(true);
        View::assign([
            'menu_child' => 'fund_index',
        ]);
        return View::fetch();
    }

    public function  onLine() {
        $default_amount = getSetting('default_fund_amount');
        $grade              = Db::name('user')->where(['id'=>$this->user_id])->value('grade');
        if($this->request->isAjax()){
            $data       = input('param.');
            if($grade == 0) return $this->err("请先进行 实名认证.");
            if($default_amount - $data['amount'] >0) return $this->err("充值金额必须大于 $ {$default_amount} .");
            if(!check_param($data['amount'] , 'zInt')) return $this->err('充值金额必须为正整数.');
            if(empty($data['upload_img'])) return $this->err('请上传图片后提交.');
            $fcModel    = new FundCheck();
            $re         = $fcModel->dataSaveNew($this->user_id , $data);
            if($re){
                return $this->scs('提交成功.');
            }else{
                return $this->err('提交失败.');
            }
        }
        $list = Db::name('setting')->select()->toArray();
        $wechat_number  = '';
        $wechat_name    = '';
        $alipay_number  = '';
        $alipay_name    = '';
        foreach ($list as $v){
            if($v['key'] == 'wechat_number')    $wechat_number=$v['value'];
            if($v['key'] == 'wechat_name')      $wechat_name=$v['value'];
            if($v['key'] == 'alipay_number')    $alipay_number=$v['value'];
            if($v['key'] == 'alipay_name')      $alipay_name=$v['value'];
        }

        View::layout(true);
        View::assign([
            'menu_child'    =>  'fund_index',
            'usa_rate'      =>  Db::name('user')->where(['id'=>$this->user_id])->value('usa_rate'),
            'sub_fund_desc' =>  getSetting('sub_fund_desc'),
            'wechat_number' =>  $wechat_number,
            'wechat_name'   =>  $wechat_name,
            'alipay_number' =>  $alipay_number,
            'alipay_name'   =>  $alipay_name,
            'grade'         =>  $grade,
            'default_amount'=>  $default_amount,
            'fund_desc'     =>  Db::name('setting')->where(['key'=>'fund_desc'])->value('desc'),
        ]);
        return View::fetch();
    }

    public function log()
    {
        if($this->request->isAjax())
        {
            $fcModel = new FundCheck();
            return $fcModel->tableData(input('param.') + ['user_id' => $this->user_id]);
        }
        View::layout(true);
        View::assign([
            'menu_child'    => 'fund_log'
        ]);
        return View::fetch();
    }

    public function account()
    {
        if($this->request->isAjax()){
            $fcModel = new UserCashLog();
            return $fcModel->tableDataIndex(input('param.') + ['user_id' => $this->user_id]);
        }
        View::assign([
            'menu_child' => 'fund_account',
        ]);
        return View::fetch();
    }

    public function card()
    {

        if($this->request->isAjax()){
            $fcModel = new FundCard();
            return $fcModel->tableDataIndex(['user_id' => $this->user_id]);
        }
        $grade              = Db::name('user')->where(['id'=>$this->user_id])->value('grade');
        View::layout(true);
        View::assign([
            'grade'         => $grade,
            'menu_child'    => 'fund_index',
        ]);
        return View::fetch();
    }


    public function cardCheck()
    {
        $value                = trim(input('post.card_num'));
        $card_pwd             = trim(input('post.card_pwd'));

        $grade      = Db::name('user')->where(['id'=>$this->user_id])->value('grade');
        if($grade == 0) return $this->err("请先进行 实名认证.");

        $cache_key            = $this->username . '_card_check_error_num';
        $card_check_error_num = Cache::store('redis')->get($cache_key);
        if($card_check_error_num >=5) return $this->err('错误次数过多,且12小时内无法正常操作.');
        if(empty($value)) return $this->err('充值码不能为空.');
        $check_list = Db::name('fund_card')->where(['value'=>$value])->find();
        if(empty($check_list)){
            if(empty($card_check_error_num)){
                Cache::store('redis')->set($cache_key, 1 , 60*60*12);
            }else{
                Cache::store('redis')->set($cache_key, $card_check_error_num + 1 , 60*60*12);
            }
        }

        if(empty($check_list)) return $this->err('充值码无效.');
        $is_used    = $check_list['is_used'];
        $amount     = $check_list['amount'];
        $id         = $check_list['id'];
        $pwd        = $check_list['pwd'];
        if($card_pwd != $pwd) return $this->err('充值码密码错误.');
        if($is_used == 1) return $this->err('充值码已使用.');
        $user_id    = $this->user_id;
        $ctime      = getUtcTime();
        $blog       = false;
        Db::startTrans();
        try{
            $user_list      = Db::name('user')->find($user_id);
            $user_balance   = $user_list['balance'];
            $result_balance = $user_balance + $amount;
            Db::name('user_cash_log')->save([
                'user_id'       => $user_id,
                'type'          => 0, //1=debit
                'action_type'   => 1, //3=消费
                'amount'        => $amount,
                'balance'       => $result_balance, //如果是进行修复的话，这里的余额要重新计算
                'desc'          => "充值码充值",
                'ctime'         => $ctime
            ]);
            $check_num  = 'C' . getRandNumber();
            Db::name('fund_check')->save([
                'user_id'       => $user_id,
                'check_num'     => $check_num,
                'amount'        => $amount,
                'balance'       => $result_balance,
                'ctime'         => $ctime,
                'utime'         => $ctime,
                'check_status'  => 1,
                'pay_type'      => 4,
                'trn'           => $value,
                'desc'          => "充值码充值",
            ]);
            Db::name('user')->where(['id'=>$user_id])->update(['balance'=>$result_balance]);
            Db::name('fund_card')->where(['id'=>$id])->update([
                'user_id'   => $user_id,
                'is_used'   => 1,
                'utime'     => $ctime
            ]);
            $blog       = true;
            Db::commit();
        } catch (\Exception $e) {
            //var_dump($e->getMessage());
            Db::rollback();
        }
        if($blog){
            return $this->scs('充值成功.');
        }else{
            return $this->err('充值失败.');
        }
    }

    public function  alipay()
    {
//        if($this->user_id != 1){
//            $this->redirect(url('/index/index'));
//        }
        $user_list          = Db::name('user')->where(['id'=>$this->user_id])->find();
        $grade              = $user_list['grade'];
        $alipay_name        = $user_list['alipay_name'];
        $redis_key_name     = 'user_alpay_data_' . $this->username;
        Cache::store('redis')->delete($redis_key_name);
        View::layout(true);
        View::assign([
            'alipay_server' => getSetting('alipay_server'),
            'usa_rate'      => Db::name('user')->where(['id'=>$this->user_id])->value('usa_rate'),
            'default_amount'=> 50,
            'grade'         => $grade,
            'alipay_name'   => $alipay_name,
            'menu_child'    => 'fund_index',
        ]);
        return View::fetch();
    }

    public function  alipayWait()
    {
//        if($this->user_id != 1){
//            $this->redirect(url('/index/index'));
//        }
        $money          = input('post.money' ,'');
        if(empty($money)){
            $this->redirect(url('/index/fund/alipay'));
        }

        $money_used     =[50,60,70,80,90,100,150];  //正式上线金额
        //$money_used     =[0.01,0.1,1.0]; //测试用金额
        $out_trade_no   = '';
        $qr_code        = '';
        $money_en       = '';

        if(!in_array($money , $money_used)){
            $error_msg = '您选择的充值金额有误,请稍后再尝试';
        }else{
            $user_list          = Db::name('user')->find($this->user_id);
            $username           = $user_list['username'];
            $grade              = $user_list['grade'];
            $alipay_name        = $user_list['alipay_name'];
            if($grade == 0){
                $this->redirect(url('/index/user/cardCheck'));
                exit;
            }
            if($alipay_name == '***'){
                $this->redirect(url('/index/user/userDetail'));
                exit;
            }

            $redis_key_name     = 'user_alpay_data_' . $username;
            $redis_data         = Cache::store('redis')->get($redis_key_name);

            if(empty($redis_data)){
                $data_list      = $this->getPayData($money,$redis_key_name);
            }else{
                $data_list      = json_decode($redis_data,true);
                $redis_money    = $data_list['money'];
                if($redis_money - $money != 0){
                    $data_list  = $this->getPayData($money,$redis_key_name);
                }
            }

            $out_trade_no   = $data_list['out_trade_no'];
            $money_en       = $data_list['money_en'];
            $qr_code        = $data_list['qr_code'];
            $error_msg      = $data_list['error_msg'];
        }
        View::layout(true);
        View::assign([
            'out_trade_no'  => substr($out_trade_no ,2),
            'qr_code'       => $qr_code,
            'money'         => $money,
            'money_en'      => $money_en,
            'error_msg'     => $error_msg,
            'menu_child'    => 'fund_index',
        ]);
        return View::fetch();
    }

    public function  msjpay()
    {
        $redis_key_name     = 'user_pockyt_data_' . $this->username;

        $user_list          = Db::name('user')->where(['id'=>$this->user_id])->find();
        $grade              = $user_list['grade'];
        $alipay_name        = $user_list['alipay_name'];
        $we_chat            = $user_list['we_chat'];

        Cache::store('redis')->delete($redis_key_name);

        View::layout(true);
        View::assign([
            'pockyt_channel_rate'   => getSetting('pockyt_channel_rate'),
            'pockyt_fund_rate'      => getSetting('pockyt_fund_rate'),
            'fund_msjpay_wx'        => getSetting('fund_msjpay_wx'),
            'fund_msjpay_alipay'    => getSetting('fund_msjpay_alipay'),
            'default_amount'        => 50,
            'grade'                 => $grade,
            'alipay_name'           => $alipay_name,
            'we_chat'               => $we_chat,
            'menu_child'            => 'fund_index',
        ]);
        return View::fetch();
    }

    public function getPayData($money,$redis_key_name)
    {
        $alipay_server  = getSetting('alipay_server');
        $usa_rate       = Db::name('user')->where(['id'=>$this->user_id])->value('usa_rate');
        $money_en       = getSprintf(round($money*(1+$alipay_server)*$usa_rate , 2));

        $out_trade_no       = 'CD' . date('YmdHis') . getRandNumber(0,9,6);
        $array=array(
            "pay_id"        => $out_trade_no,
            "money"         => $money_en,
            "notify_url"    => "https://www.cardecho.com/api/AcceptZf/notify_url",
        );
        $res  = (new Pay)->startPay($array);

        $qr_code      = '';
        $error_msg    = '';
        $msg          = '';
        $blog         = false;

        if($res['code'] == 1){
            $out_trade_no   = $res['data']['out_trade_no'];
            $qr_code    = $res['data']['qr_code'];
            $blog           = true;
            $redis_list     = json_encode([
                'out_trade_no'  => $out_trade_no,
                'qr_code'       => $qr_code,
                'money'         => $money,
                'money_en'      => $money_en,
                'error_msg'     => ''
            ]);
            //增加进程是否开始，防止重复建卡 //并且时间时间是60秒
            Cache::store('redis')->set($redis_key_name, $redis_list , 5*60);
        }else{
            $msg            = iconv("GBK" , "UTF-8" ,$res['msg']);
            $error_msg      = '支付宝创建订单二维码失败,请稍后再尝试';
        }
        $aa = [
            'user_id'       => $this->user_id,
            'out_trade_no'  => $out_trade_no,
            'amount'        => $money,
            'amount_en'     => $money_en,
            'status_api'    => ($blog)?1:0,
            'msg'           => $msg,
            'ctime'         => getUtcTime()
        ];
        $bb = Db::name('user_pay')->save($aa);
        return [
            'money_en'      => $money_en,
            'out_trade_no'  => $out_trade_no,
            'error_msg'     => $error_msg,
            'qr_code'       => $qr_code,
            'money'         => $money,
        ];
    }

    //接口提交
    public function checkTrade()
    {
        $mcard = input('get.mcard');
        $list  = Db::name('user_pay')->where(['out_trade_no' => 'CD' . $mcard])->find();
        $status_check   = $list['status_check'];
        if($status_check != 0){
            $redis_key_name     = 'user_alpay_data_' . $this->username;
            Cache::store('redis')->delete($redis_key_name);
        }
        return $this->scs('','',['check'=>$status_check]);
    }

    //生成签名
    public static function generateSign($data,$apiToken=''){
        if(array_key_exists('sign_type',$data)){
            unset($data['sign_type']);
        }
        ksort($data);
        $string=self::formatUrlParams($data).'&'.$apiToken;
        //MD5加密
        $string=md5($string);
        return strtolower($string);
    }
    //格式化参数格式化成url参数
    public static function formatUrlParams(array $data) {
        $buff = "";
        foreach ($data as $k => $v) {
            if ($k != "signature" && $v !== "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    public function usdt()
    {
        $user_id = $this->user_id;
        if($user_id < 919){
            if($user_id==5 || $user_id==770){
            }else{
                $this->redirect(url('/index/fund'));
            }
        }
        //判断是否有USDT的用户设置
        $is_user_oy_set = Db::name('user_oy_set')->where(['user_id' => $this->user_id])->find();

        //判断是否有未完成的USDT支付
        $fund_usdt_list = Db::name('fund_check_oy')->where([
            'user_id' => $this->user_id,
            'status_check' => 0
        ])->find();
        if($fund_usdt_list){
            $this->redirect(url('/index/fund/usdtPay'));
        }
        $user_list          = Db::name('user')->where(['id'=>$this->user_id])->find();
        $grade              = $user_list['grade'];
        $rate               = $is_user_oy_set['rate'] ?? getSetting('usdt_default_rate');
        $money_array        = getSetting('usdt_fund_array');
        $money_used         = explode("," , $money_array);  //正式上线金额
        View::layout(true);
        View::assign([
            'money_array'   => $money_used,
            'grade'         => $grade,
            'rate'          => $rate,
            'menu_child'    => 'fund_index',
        ]);
        return View::fetch();
    }

    public function  usdtPay()
    {
        $user_id = $this->user_id;
        if($user_id < 919){
            if($user_id==5 || $user_id==770){
            }else{
                $this->redirect(url('/index/fund'));
            }
        }
        //判断是否有USDT的用户设置
        $is_user_oy_set = Db::name('user_oy_set')->where(['user_id' => $this->user_id])->find();

        $oy_rate           = $is_user_oy_set['rate'] ?? getSetting('usdt_default_rate');
        $fund_usdt_list = Db::name('fund_check_oy')->where([
            'user_id' => $this->user_id,
            'status_check' => 0
        ])->order('id desc')->find();
        $blog_error      = "";
        $ctime           = getUtcTime(false);
        $qr_code         = getSetting('oy_fund_user');
        $oy_show         = "https://api.qrserver.com/v1/create-qr-code/?size=150%C3%97150&data=" . urlencode($qr_code);

        if(!empty($fund_usdt_list)){
            $blog           = 2;
            $fund_usdt_id   = $fund_usdt_list['id'];
            $money_rate     = $fund_usdt_list['amount_real'];
            $money_old      = $fund_usdt_list['amount'];
            $out_trade_no   = $fund_usdt_list['out_trade_no'];
            $db_ctime       = $fund_usdt_list['ctime'];
            $ht_time        = 1800 - (strtotime($ctime) - strtotime($db_ctime));
        }else{
            $ht_time         = 1800;
            $money           = input('post.money' ,0);
            $blog            = 1;

            $out_trade_no    = '';
            $money_rate      = intval($money + ($money * $oy_rate));
            $money_old       = $money;
            if(!empty($money)){
                $money_array    = getSetting('usdt_fund_array');
                $money_used     = explode("," , $money_array);  //正式上线金额
                if(!in_array($money , $money_used)){
                    $blog_error = '您选择的充值金额有误,请稍后再尝试';
                }else{
                    $money_rate      = (float)($money_rate . '.' . getRandNumber(1,9,4));
                    $out_trade_no    = 'OY' . date('YmdHis') . getRandNumber(0,9,6);
                    Db::name('fund_check_oy')->save([
                        'user_id'       => $this->user_id,
                        'out_trade_no'  => $out_trade_no,
                        'amount'        => $money, //实冲金额
                        'amount_real'   => $money_rate, //充值金额
                        'ctime'         => $ctime,
                        'pay_user'      => $qr_code
                    ]);
                    $blog = 2;
                }
            }else{
                $blog_error = '充值金额不能为空.';
            }
        }
        View::layout(true);
        View::assign([
            'money'         => $money_rate,
            'money_old'     => $money_old,
            'blog'          => $blog,
            'error_msg'     => $blog_error,
            'address'       => $qr_code,
            'out_trade_no'  => substr($out_trade_no , 2),
            'oy_show'       => $oy_show,
            'menu_child'    => 'fund_index',
            'ht_time'       => $ht_time
        ]);
        return View::fetch();
    }

    public function usdtError()
    {
        $user_id = $this->user_id;
        if($user_id < 919){
            if($user_id==5 || $user_id==770){
            }else{
                $this->redirect(url('/index/fund'));
            }
        }

        $is_user_oy_set = Db::name('user_oy_set')->where(['user_id' => $this->user_id])->find();

        $error_msg = '';
        if($this->request->post())
        {
            $ctime          = getUtcTime(false);
            $money          = trim(input('post.money'));
            $time           = trim(input('post.time'));
            $usdt_history   = trim(input('post.usdt_history'));
            $trx_hash       = trim(input('post.trx_hash'));
            if(is_numeric($money)){
                if($money - 100000>0 || $money <0){
                    $error_msg = '实际付款超额.';
                }else{
                    $parts = explode('.',(string)$money);
                    if (count($parts) > 1) {
                        $decimalPlaces = strlen($parts[1]);
                    } else {
                        $decimalPlaces = 0;
                    }
                    if($decimalPlaces >4){
                        $error_msg = '付款金额小数点不能超过4位.';
                    }else{
                        $out_trade_no = Db::name('fund_check_oy')
                            ->where(['id'=>$usdt_history])->value('out_trade_no');
                        $chenck_return_list = Db::name('fund_check_oy_return')
                            ->where([
                                'user_id'=>$this->user_id,
                                'is_ok'  =>0,
                            ])->find();
                        if(!empty($chenck_return_list)){
                            $error_msg = "您有'未处理'的申请工单,请勿重复提交.";
                        }else{
                            Db::name('fund_check_oy_return')->save([
                                'user_id'       => $this->user_id,
                                'error_time'    => $time,
                                'trx_hash'      => $trx_hash,
                                'amount'        => $money,
                                'ctime'         => $ctime,
                                'out_trade_no'  => $out_trade_no
                            ]);
                            $error_msg = '工单申请成功';
                        }
                    }
                }
            }else{
                $error_msg = '实际付款必须是数字.';
            }
        }
        $check_gd_array = [];
        $check_return_list = Db::name('fund_check_oy_return')
            ->where([
                'user_id'=>$this->user_id,
                'is_ok'  =>0
            ])->select()->toArray();

        foreach($check_return_list as $v_check){
            $check_gd_array[] = $v_check['out_trade_no'];
        }
        $start_time = date('Y-m-d H:i:s' , strtotime('-3 days'));
        $show_array = [];
        $list_error_array = Db::name('fund_check_oy')->where([
            'user_id' => $this->user_id,
            'status_check' => 4
        ])->field('ctime,amount_real,id,out_trade_no')
            ->where("ctime >='{$start_time}'")
            ->order('ctime desc')->select()->toArray();
        if(empty($list_error_array)){
            $error_msg = '取消充值历史为空.';
        }else{
            foreach($list_error_array as $v_oy){
                $out_trade_no = $v_oy['out_trade_no'];
                if(!in_array($out_trade_no , $check_gd_array))
                {
                    $show_array[] = $v_oy;
                }
            }
        }

        View::layout(true);
        View::assign([
            'list_array'    => $show_array,
            'error_msg'     => $error_msg,
            'menu_child'    => 'fund_index',
        ]);
        return View::fetch();
    }

    public function  usdtCancel()
    {
        $otn           = input('get.otn' ,'');
        if(empty($otn)){
            $this->redirect(url('/index/fund/usdt'));
        }else{
            $otn = 'OY' . $otn;
            $check_fund_list = Db::name('fund_check_oy')
                ->where(['out_trade_no'=>$otn])->find();
            if(empty($check_fund_list)){
                $this->redirect(url('/index/fund/usdt'));
            }else{
                $oy_id = $check_fund_list['id'];
                Db::name('fund_check_oy')->where(['id'=>$oy_id])
                    ->update([
                        'status_check' => 4,
                        'utime'        => getUtcTime(false)
                    ]);
                $this->redirect(url('/index/fund/usdt'));
            }
        }
    }

    public function usdtReturnLog()
    {
        if($this->request->isAjax())
        {
            $fcModel = new FundCheckOyReturn();
            return $fcModel->tableDataAdmin(input('param.') + ['user_id' => $this->user_id]);
        }
        View::layout(true);
        View::assign([
            'menu_child'    => 'fund_log'
        ]);
        return View::fetch();
    }

    public function usdtFundLog()
    {
        if($this->request->isAjax())
        {
            $fcModel = new FundCheckOy();
            return $fcModel->tableDataAdmin(input('param.') + ['user_id' => $this->user_id]);
        }
        View::layout(true);
        View::assign([
            'menu_child'    => 'fund_log'
        ]);
        return View::fetch();
    }

    public function oyCheckTrade()
    {
        $mcard          = input('get.mcard');
        $list           = Db::name('fund_check_oy')->where(['out_trade_no' => 'OY' . $mcard])->find();
        $status_check   = $list['status_check'];

        return $this->scs('','',['check'=>$status_check]);
    }

    public function qrShow()
    {
        header('Content-Type: image/png');
        $text = $_GET['text'] ?? 'default';
        //计算图片尺寸
        $width = 150;
        $size = floor($width / 37 * 100) / 100 + 0.01;
        $errorCorrectionLevel = intval(2);//容错级别
        $matrixPointSize = intval($size); //生成图片大小
        $margin = 0;//外边距离(白边)
        QRcode::png($text, false,
            $errorCorrectionLevel,
            $matrixPointSize, $margin);
        //QRcode::png($text);
    }
}
